package edu.uj.petri.view;

import edu.uj.petri.commands.Restorable;
import edu.uj.util.Observed;
import edu.uj.util.Observer;
import edu.uj.util.ObserverList;
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.awt.geom.Point2D;

/**
 * represents element which can be drawn on a diagram.
 *
 * <p>All coordinates (points, rectangles etc.) are given in abstract Units
 * from {@link Canvas}.</p>
 *
 * @author Piotrek
 */
public abstract class DiagramElement implements Serializable, Observed, Restorable {
    
    // TODO protected Color getSelectedColor() ?
    
       
    // kolory
    protected static final Color UNSELECTED_COLOR = Color.BLACK;
    protected static final Color SELECTED_COLOR = Color.BLUE;
    
    protected boolean selected = false;
    protected boolean removed = false;
    
    protected ObserverList observerList = new ObserverList();
    
    public static final int REDRAW = 4567;
        
    public DiagramElement() {
        observerList = new ObserverList();
    }

    /**
     * checks if this element contains given point
     * @param point on canvas with coordinates given in {@link Canvas Units}.
     */
    public abstract boolean containsPoint(Point2D point);

    /** checks if this element is inside or collides with given rect */
    public abstract boolean crossesRectangle(Rectangle2D rect);

    /** draws element on given canvas */
    public abstract void draw(Canvas canvas);

    /** makes element selected/unselected */
    public void setSelected(boolean selected) {
        
        this.selected = selected;
    }

    /** asks element whether it can be moved by clicking on given point */
    public abstract boolean canBeMoved(Point2D startPoint);

    /** moves object according to moving mouse from start point to end point */
    public abstract void move(Point2D start, Point2D end);

    /** responds to double mouse click */
    public abstract void doubleClick( Point2D point );

    /** returns element context menu */
    public abstract ContextMenu getContextMenu();

    /** removes element from view and data from model */
    public abstract void removeFrom(View view); // TODO Document instead of View?
    
    public void subscribe(Observer o) {
        observerList.subscribe(o);
    }

    public void unsubscribe(Observer o) {
        observerList.unsubscribe(o);
    }
}
